﻿using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace Core.Framework.Util.Common
{
    /// <summary>
    /// 请求代理
    /// </summary>
    public class HttpProxy
    {
        /// <summary>
        /// 开始
        /// </summary>
        /// <param name="service">服务地址</param>
        /// <param name="token">用户身份签名</param>
        /// <param name="context">请求上下文</param>
        /// <returns></returns>
        public static string Start( string service, string token, HttpContext context)
        {

            // service = "localhost:59803";

            // 请求地址 {service}
            var uri = $"http://{service}{context.Request.Path}{context.Request.QueryString.ToString()}";

            // 返回参数
            Task<string> result;

            // 创建请求客户端
            HttpClient httpClient = CreateHttpClient(uri);

            // POST PUT 请求参数
            StringContent bodyData = new StringContent(string.Empty);


            // 设置 Header 
            foreach (var item in context.Request.Headers)
            {
                switch (item.Key.ToLower())
                {
                    case "referer":
                    case "cookie":
                    case "accept-encoding":
                    case "accept-language":
                    case "accept":
                    case "origin":
                    case "user-agent":
                    case "sec-fetch-mode":
                    case "x-original-proto":
                    case "x-original-for":
                    case "ms-aspnetcore-token":
                    case "sec-fetch-site":
                    case "x-requested-with":
                        break;
                    case "host":
                        httpClient.DefaultRequestHeaders.TryAddWithoutValidation(item.Key, service);
                        break;
                    default:
                        httpClient.DefaultRequestHeaders.TryAddWithoutValidation(item.Key, item.Value.ToString());
                        break;
                }
            }

            httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Itool-Token", token);

            switch (context.Request.Method.ToLower())
            {
                default:
                case "put":
                case "post":
                    // 构造请求参数
                    var body = new StreamReader(context.Request.Body).ReadToEndAsync().Result;
                    bodyData = new StringContent(body);
                    bodyData.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
                    break;
            }



            switch (context.Request.Method.ToLower())
            {
                case "get":
                    result = httpClient.GetAsync(uri).Result.Content.ReadAsStringAsync();
                    break;
                case "delete":
                    result = httpClient.DeleteAsync(uri).Result.Content.ReadAsStringAsync();
                    break;
                case "put":
                    result = httpClient.PutAsync(uri, bodyData).Result.Content.ReadAsStringAsync();
                    break;
                case "post":
                default:
                    result = httpClient.PostAsync(uri, bodyData).Result.Content.ReadAsStringAsync();
                    break;
            }


            return result.Result;

        }


        /// <summary>
        /// 创建HttpClient
        /// </summary>
        /// <returns></returns>
        private static HttpClient CreateHttpClient(string url, IDictionary<string, string> cookies = null)
        {
            HttpClient httpclient;
            HttpClientHandler handler = new HttpClientHandler();

            var uri = new Uri(url);
            if (cookies != null)
            {
                foreach (var key in cookies.Keys)
                {
                    string one = key + "=" + cookies[key];
                    handler.CookieContainer.SetCookies(uri, one);
                }
            }
            //如果是发送HTTPS请求  
            if (url.ToLower().StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
                httpclient = new HttpClient(handler);
            }
            else
            {
                httpclient = new HttpClient(handler);
            }
            return httpclient;
        }

        
    }
}
